#! /usr/bin/env python

from openpyxl import load_workbook
import argparse
import copy, json,re, os, commands
import sys
import collections

class REGISTER:
    pass

class FIELD:
    pass

regfiles = {}

range_dict = {
    "A" : "offset", 
    "B" : "name", 
    "C" : "field", 
    "D" : "msb", 
    "E" : "lsb", 
    "F" : "access_type", 
    "G" : "default_value", 
    "H" : "scurity_access", 
}

reload(sys)
sys.setdefaultencoding('utf-8')

parser = argparse.ArgumentParser(description='system register XML parser')
parser.add_argument('-f', '--file', nargs="+", dest="filelib", \
               help="give the test list that should be run")
parser.add_argument('-l', '--list', action='store_true', dest="list", default=False, \
               help="list all the test in the testplan")
opts = parser.parse_args() 


for f in opts.filelib:
    filename = "%s/%s"%(os.getcwd(), f)
    xml_file = f.replace(".xlsx", ".xml")
    regfiles[xml_file] = []
    assert os.path.isfile(filename), "No file named %s"%(filename)

    wb =  load_workbook(filename = filename)

    assert "register_bank" in wb.get_sheet_names(), "No valid sheet in wb %s"%(filename)
    sheet_ranges = wb["register_bank"]

    column=len(sheet_ranges['A'])
    line=len(sheet_ranges['2'])
    assert  column != 0, "no contents in sheets column"
    assert  line != 0, "no contents in sheets line"

    reg = None
    array_num = 1
    for i in range(2, column+1):
      if sheet_ranges["A%s"%(i)].value != None:
        if reg !=None:
          regfiles[xml_file].append(copy.deepcopy(reg))
          if array_num >1:
            for iter in range(1, array_num):
              array_reg = copy.deepcopy(reg)
              array_name = "%s%s"%(array_reg.name, iter)
              array_reg.name = array_name
              array_offset = str(hex(int(array_reg.offset, 16)+iter*0x4))
              array_reg.offset = array_offset
              regfiles[xml_file].append(copy.deepcopy(array_reg))
              
          array_num = 1
        
        offset=sheet_ranges["A%s"%(i)].value.strip(" ")
        name=sheet_ranges["B%s"%(i)].value.strip(" ")
        field=sheet_ranges["C%s"%(i)].value.strip(" ")
        msb=sheet_ranges["D%s"%(i)].value
        lsb=sheet_ranges["E%s"%(i)].value
        access=sheet_ranges["F%s"%(i)].value.strip(" ")
        default=sheet_ranges["G%s"%(i)].value.strip(" ")
        security=sheet_ranges["H%s"%(i)].value.strip(" ")
        if "+[" in offset: 
            offset = offset.strip(" ") 
            array_num = int(offset.split("+[")[1].split("*0x04]")[0])
            offset=str(hex(int(offset.split("+[")[0], 16)))

        reg = REGISTER()
        setattr(reg, "fields", collections.OrderedDict())
        setattr(reg, "name", "%s"%(name))
        setattr(reg, "offset", "%s"%(offset))

        if field != "NA":
            field_obj = FIELD() 
            setattr(field_obj, "name", field)
            setattr(field_obj, "msb", msb)
            setattr(field_obj, "lsb", lsb)
            setattr(field_obj, "access", access)
            setattr(field_obj, "default", default)
            setattr(field_obj, "security", security)
            reg.fields[field] = field_obj
      else :
        field=sheet_ranges["C%s"%(i)].value.strip(" ")
        msb=sheet_ranges["D%s"%(i)].value
        lsb=sheet_ranges["E%s"%(i)].value
        access=sheet_ranges["F%s"%(i)].value.strip(" ")
        default=sheet_ranges["G%s"%(i)].value.strip(" ")
        security=sheet_ranges["H%s"%(i)].value.strip(" ")

        if field != "NA":
            field_obj = FIELD() 
            setattr(field_obj, "name", field)
            setattr(field_obj, "msb", msb)
            setattr(field_obj, "lsb", lsb)
            setattr(field_obj, "access", access)
            setattr(field_obj, "default", default)
            setattr(field_obj, "security", security)
            reg.fields[field] = field_obj


head = '''
<!--
   Copyright (C) [2024] Xingyun Integrated Circuit Co., Ltd.

  GreenCode was a private technology asset of Xingyun Integrated Circuit, Inc (Confidential)
  Author: Shawn.Tan
  Date : 2025.10.28

  History : Initial Version 2025.10.28
-->
'''
physical_regs_head='''<?xml version="1.0" encoding="utf-8"?>
<registers>
  <physical_registers>
'''
physical_regs_tail='''  </physical_registers>
'''

register_file_head = '''  <register_file name="GPGPU Registers">
'''
register_file_tail='''  </register_file>
'''
xml_end ='''</registers>
'''
for rf in regfiles.keys(): 
    with open(rf, "w") as xml:
      # physical registers
      regs = regfiles[rf]
      xml.write(head)
      xml.write(physical_regs_head)

      for r in regs:
        phy_reg = '''    <physical_register index="%s" name="%s" size="32", reset="0" type="SysReg"/> 
'''%(r.offset, r.name)
        xml.write(phy_reg)
      xml.write(physical_regs_tail)

      xml.write(register_file_head)

      for i in regs :
        sys_reg = '''    <register boot="0" index="%s" name="%s" size="32" type="SysReg">
'''%(i.offset, i.name)
        xml.write(sys_reg)
        for fd in i.fields.keys():
          msb = i.fields[fd].msb
          lsb = i.fields[fd].lsb
          size=int(msb)-int(lsb)+1
          field_name = '''      <register_field name="%s" physical_register="%s" size="%s">
'''%(fd, i.name, size)
          xml.write(field_name)
          field_def = '''        <bit_field shift="%s" size="%s"/>
'''%(lsb, size)
          xml.write(field_def)
          field_end = '''      </register_field>
'''
          xml.write(field_end)
        
        xml.write('''    </register>
''')
      xml.write(register_file_tail)

      xml.write(xml_end)

           
    
       
    
   